#pragma once
 
namespace Melting
{
	typedef char PackFilePath[ FS_FILE_NAME_MAX + 1 ];
	
	/**
		A PackFile is an archive file, containing many different files
	*/
	class PackFile
	{
		static const ULONG READ_ALL_DATA_IN_FILE = 0xFFFFFFFF;
	
	public:

		/// CTOR
		PackFile( void );
		
		/// DTOR
		~PackFile( void );
		
		/**
			Constructor. Open the file.
			@see Open.
			@param _strPackFilePath The path of the pack file.
		*/
		PackFile( const PackFilePath _strPackFilePath );
		 
		///	Open the pack file at the given path
		void				Open( const PackFilePath _strPackFilePath );

		///	Is the pack file opened?
		inline bool			IsOpen( void ) const;
		
		///	Close the pack file. @remark After this operation you can not get a file.
		inline void			Close( void );
		

		///	Get the number of files included in the pack.
		ULONG				GetFileCount( void ) const { return mulFileCount; }
		 
		/**
			Read a file included in the pack.
			@remark pubBuffer must be allocated.
			@param _ulIndex The index of the file.
			@param _pubBuffer The raw memory used to stock the file.
			@param _ulSizeOfBuffer Size of the raw memory used to stock the file.
			@param _ulBytesToRead nb of bytes to read
			@param _ulOffsetInFile offset within the file from which we will start reading
		*/
		void				ReadFile( ULONG _ulIndex,  UBYTE* _pubBuffer, ULONG _ulSizeOfBuffer, ULONG _ulOffsetInFile = 0, ULONG _ulBytesToRead = READ_ALL_DATA_IN_FILE );
		
		/**
			Read a file included in the pack. 
			Allocate the buffer used to stock the found file.
			@param ulIndex The index of the file.
			@param pubBuffer The raw memory used to stock the file.
		*/
		void				ReadFileAndAllocate( ULONG ulIndex, UBYTE*& pubBuffer );
		 
		
		/**
			Get the offset in the pack file of a file.
			@param ulIndex The index of the file.
		*/
		inline ULONG		GetFileOffset( ULONG ulIndex );
		
		/**
			Get the size of a file included in the pack.
			@param ulIndex The index of the file.
		*/
		inline ULONG		GetFileSize( ULONG ulIndex );
		
	private:
	
		struct FileInfo 
		{
			ULONG mulOffset;			///< Offset of a file included in the pack.
			ULONG mulSize;				///< Size of a file included in the pack.
		};
	
		ULONG 					mulFileCount;	///< The number of files included in the pack.
		FileInfo* 				maFileInfo;		///< Information of files. ( couple of offset-size )
		Melting::File 			mPackFile;		///< The file object used to read the pack.
		bool					mbIsOpen;		///< Is the pack file opened?

		///	Constructor by copy. Forbidden access.
		PackFile( const PackFile& other );
		
		///	Copy operator. Forbidden access.
		const PackFile& operator=( const PackFile& other );
	};
	
	//-------------------------------------------------------------------------------------
	//	Is the pack file opened?
	//-------------------------------------------------------------------------------------
	bool PackFile::IsOpen( void ) const { return mbIsOpen; }
	
	//-------------------------------------------------------------------------------------
	//	Close the pack file. @remark After this operation you can not get a file.
	//-------------------------------------------------------------------------------------
	void PackFile::Close( void )
	{
		mPackFile.Close( );
		mbIsOpen = false;
	}
	
	//-------------------------------------------------------------------------------------
	//-------------------------------------------------------------------------------------
	inline ULONG PackFile::GetFileOffset( ULONG ulIndex )
	{
		//--------------------
		// pre condition
		MB_ASSERT( ulIndex < mulFileCount, 	"PackFile::GetFile : Index is out of range" );
		//--------------------
		
		return maFileInfo[ ulIndex ].mulOffset;
	}
		
	//-------------------------------------------------------------------------------------
	//-------------------------------------------------------------------------------------
	inline ULONG PackFile::GetFileSize( ULONG ulIndex )
	{
		//--------------------
		// pre condition
		MB_ASSERT( ulIndex < mulFileCount, 	"PackFile::GetFile : Index is out of range" );
		//--------------------
		
		return maFileInfo[ ulIndex ].mulSize;
	}

}
